﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management;
using System.Text;
using WMI.NET.Abstracts;
using WMI.NET.CIM;

namespace WMI.NET.ComputerSystemHardware.InputDevice
{
    /// <summary>
    /// The Win32_PointingDevice WMI class represents an input device used to point to and select regions on the display of a computer system running Windows. Any device used to manipulate a pointer, or point to the display on a computer system running Windows is a member of this class.
    /// </summary>
    public class Win32_PointingDevice : CIM_PointingDevice
    {

        private Nullable<UInt16> _DeviceInterface;
        private Nullable<UInt32> _DoubleSpeedThreshold;
        private string _HardwareType;
        private string _InfFileName;
        private string _InfSection;
        private string _Manufacturer;
        private Nullable<UInt32> _QuadSpeedThreshold;
        private Nullable<UInt32> _SampleRate;
        private Nullable<UInt32> _Synch;

        /// <summary>
        /// Type of interface used for the pointing device.
        /// </summary>
        public Nullable<UInt16> DeviceInterface { get { return _DeviceInterface; } } //TODO enum

        /// <summary>
        /// One of two acceleration values. The sensitivity of the pointing device doubles (toggles from the first to the second value) when the pointing device moves a distance greater than this threshold value.
        /// </summary>
        public Nullable<UInt32> DoubleSpeedThreshold { get { return _DoubleSpeedThreshold; } }

        /// <summary>
        /// Type of hardware used for the Windows pointing device.
        /// Example: "MICROSOFT PS2 MOUSE"
        /// </summary>
        public string HardwareType { get { return _HardwareType; } }

        /// <summary>
        /// Name of the .inf file for the Windows pointing device.
        /// Example: "ab.inf"
        /// </summary>
        public string InfFileName { get { return _InfFileName; } }

        /// <summary>
        /// Section of the .inf file that holds configuration information for the Windows pointing device.
        /// </summary>
        public string InfSection { get { return _InfSection; } }

        /// <summary>
        /// Name of the processor's manufacturer.
        /// Example: "GenuineSilicon"
        /// </summary>
        public string Manufacturer { get { return _Manufacturer; } }

        /// <summary>
        /// One of two acceleration threshold values. The system doubles the speed of the pointer movement when the pointer device moves a distance greater than this value. Because this speed increase occurs after the DoubleSpeedThreshold value has been met, the pointer effectively moves at four times its original speed.
        /// </summary>
        public Nullable<UInt32> QuadSpeedThreshold { get { return _QuadSpeedThreshold; } }

        /// <summary>
        /// Rate at which the pointing device is polled for input information.(Hertz) 
        /// </summary>
        public Nullable<UInt32> SampleRate { get { return _SampleRate; } }

        /// <summary>
        /// Length of time after which the next interrupt is assumed to indicate the start of a new device packet (partial packets are discarded). In the event that an interrupt is lost, this allows the pointing device driver to synchronize its internal representation of the packet state with the hardware state.(100 Nanoseconds) 
        /// </summary>
        public Nullable<UInt32> Synch { get { return _Synch; } }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mbo"></param>
        public Win32_PointingDevice(ManagementBaseObject mbo)
            : base(mbo)
        {
            _DeviceInterface = mbo.GetUshortValue("DeviceInterface");
            _DoubleSpeedThreshold = mbo.GetUIntValue("DoubleSpeedThreshold");
            _HardwareType = mbo.GetStringValue("HardwareType");
            _InfFileName = mbo.GetStringValue("InfFileName");
            _InfSection = mbo.GetStringValue("InfSection");
            _Manufacturer = mbo.GetStringValue("Manufacturer");
            _QuadSpeedThreshold = mbo.GetUIntValue("QuadSpeedThreshold");
            _SampleRate = mbo.GetUIntValue("SampleRate");
            _Synch = mbo.GetUIntValue("Synch");
        }

    }


    /// <summary>
    /// 
    /// </summary>
    public class GetWin32_PointingDevices : Win32Collection<Win32_PointingDevice>
    {

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override ReadOnlyCollection<Win32_PointingDevice> GetCollection()
        {
            List<Win32_PointingDevice> tempCollection = new List<Win32_PointingDevice>();

            foreach (var s in searcher.Get())
            {
                Win32_PointingDevice tempListItem = new Win32_PointingDevice(s);
                tempCollection.Add(tempListItem);
            }

            return tempCollection.AsReadOnly();
        }

        /// <summary>
        /// 
        /// </summary>
        public GetWin32_PointingDevices() : base("SELECT * FROM Win32_PointingDevice") { }

    }

}
